#pragma once

#include "stdafx.h"

using std::vector;

template <typename T>
class Matrix
{
public:
	Matrix(size_t const& _row, size_t const& _column);
	~Matrix(void) throw ()
	{
	}
	typedef Matrix<T> MatrixType;
	T const& at(size_t const& _row, size_t const& _column) const throw(std::invalid_argument)
	{
		try
		{
			return at(addrInterpret(_row, _column));
		}
		catch (std::invalid_argument* e)
		{
			throw;
		}
	}
	T & at(size_t const& _row, size_t const& _column) throw(std::invalid_argument)
	{
		try
		{
			return at(addrInterpret(_row, _column));
		}
		catch (...)
		{
			throw;
		}
	}
	T const& at(size_t const& _i) const
	{
		return matrix.at(_i);
	}
	T & at(size_t const& _i)
	{
		return matrix.at(_i);
	}
	std::vector<T> const * toVector() const
	{
		return &matrix;
	}
	size_t getRow() const throw () { return row; }
	size_t getColumn() const throw () { return column; }
	size_t size() const throw() {return matrix.size();}
private:
	size_t row, column;
	vector<T> matrix;

	//Coordinate interpret.
	size_t const addrInterpret(size_t const& _row, size_t const& _column) throw(std::invalid_argument)
	{
		if (_column >= column || _row >= row)
		{
			throw std::invalid_argument("bad subscribing index in matrix");
		}
		return (_row * column + _column);
	}
};

template <typename T>
Matrix<T>::Matrix(size_t const& _row, size_t const& _column) throw(std::invalid_argument)
: column(_column), row(_row) 
{
	if (column <= 0 || row <= 0)
	{
		throw std::invalid_argument("error para to init matrix");
	}
	matrix = std::vector<T> (column*row, 0);
}
